﻿/// -----------------------------------------------------------------
/// MVEContent.svc: the service class that implements IMVEService interface.
/// License: see http://mve.codeplex.com/license; All Rights follows the MS-PL
/// Current owner: shiniwa
/// The project decription: please refer to http://codeplex.com/mve/
/// -----------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;

namespace MVEContentSvc
{
    // MVEContentService: this is ported from MVEPublicService
    public class MVEContentService : IMvePublicService
    {
        private string GetDBConnectionString()
        {
			return ConfigurationManager.AppSettings["connectionString"];
        }


        #region Login / Logoff
        /// <summary>
        /// Logon a User to the MVE Public Service.
        /// </summary>
        /// <remarks>Done</remarks>
        /// <param name="logonId">User Name</param>
        /// <param name="password">Password</param>
        /// <returns>A Guid that has been reserved for the user in the Service.</returns>
        public Guid LogOn(string logonId, string password)
        {
            Guid Result = Guid.Empty;
            SqlConnection connection = null;

            try
            {
                //Open DB connection
                connection = DBConnectionHandler.OpenDBConnection(
                    this.GetDBConnectionString());

                int? userDbId = null;
                if (UserManager.VerifyUserCredentials
                    (logonId, password, ref userDbId, connection) == true)
                {
                    if (userDbId.HasValue)
                    {
                        int confirmedUserDbId = userDbId.Value;
                        Result = UserManager.RegisterUserLogin(logonId, confirmedUserDbId);
                    }
                    else
                    {
                        throw new ArgumentNullException(
                            "The userDbId could not be confirmed by the logon process.");
                    }
                }
                else
                    return Guid.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = Guid.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'Empty'
            return Result;
        }//end:LogOn

        /// <summary>
        /// Removes a user from the global UserManager's list of 
        /// logged in users.
        /// </summary>
        /// <remarks>Done</remarks>
        /// <param name="userId">The serviceID of the user to remove. This is the ID the user received when logging in to the service.</param>
        /// <returns>True if the user was successfully logged off.</returns>
        public bool LogOff(Guid userId)
        {
            bool Result = false;
            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    if (UserManager.RegisterUserLogoff(userId) == true)
                        Result = true;
                    else
                        Result = false;
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'
            return Result;
        }//end:LogOff
        #endregion

        #region Clips
        /// <summary>
        /// Gets all the Clips registered for the given User Id.
        /// </summary>
        /// <remarks>Not Implemented. Was never called in original Service.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string QueryClips(Guid userId)
        {
            throw new NotImplementedException(
                Resources.NotImplementedInOriginal);
        }//end:QueryClips

        /// <summary>
        /// Gets a list of all the segments that make up a clip with the given Id.
        /// </summary>
        /// <remarks>Not Implemented. Was never called in original Service.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="clipId"></param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string ClipSegments(Guid userId, int clipId)
        {
            throw new NotImplementedException(
                Resources.NotImplementedInOriginal);
        }//end:ClipSegments

        /// <summary>
        /// Gets a single Clip out of the DB.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="clipId"></param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string Clip(Guid userId, int clipId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    //Open DB connection
                    connection = DBConnectionHandler.OpenDBConnection(
                        this.GetDBConnectionString());

                    Result = ClipOperations.ClipManipulator.GetClip(
                        clipId, connection);
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            return Result;
        }//end:Clip

        /// <summary>
        /// Gets a single Clip out of the DB, given a segment Id that belongs to that Clip.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId"></param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string ClipBySegmentId(Guid userId, int segmentId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    //Open DB connection
                    connection = DBConnectionHandler.OpenDBConnection(
                        this.GetDBConnectionString());

                    Result = ClipOperations.ClipManipulator.GetClipBySegmentId(
                        segmentId, connection);
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:ClipBySegmentId
        #endregion

        #region Keyword
        /// <summary>
        /// Query the DB for segments that contain the given Keyword.
        /// Currently the maximum length of the keyword is 64 characters.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="keyword">The keyword to match. Max Length = 64 characters.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string QuerySegmentByKeyword(Guid userId, string keyword)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = KeywordOperations.KeywordManipulator.QuerySegmentByKeyword(
                            userDbId.Value, keyword, connection);
                    }
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                //Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:QuerySegmentByKeyword

        /// <summary>
        /// Query the DB for all keywords registered for the given userId.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string QueryKeywords(Guid userId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = KeywordOperations.KeywordManipulator.QueryKeywordsForUser(
                            userDbId.Value, connection);
                    }
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:QueryKeywords

        /// <summary>
        /// Registers a new Keword for a given segment.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId">Id of the segment for which to register a new keyword.</param>
        /// <param name="keyword">The Keyword to register.</param>
        /// <returns>True if the Keyword was registered successfully.</returns>
        public bool AddKeywordToSegment(Guid userId, int segmentId, string keyword)
        {
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = KeywordOperations.KeywordManipulator.AddKeywordToSegment(
                            userDbId.Value, segmentId, keyword, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
        }//end:AddKeywordToSegment

        /// <summary>
        /// Deletes the given Keyword from the Users register.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="keywordId">Id of the Keyword to Delete.</param>
        /// <returns>True if the Keyword was deleted successfully.</returns>
        public bool DeleteKeyword(Guid userId, int keywordId)
        {
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = KeywordOperations.KeywordManipulator.DeleteKeywordById(
                            userDbId.Value, keywordId, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
        }//end:DeleteKeyword
        #endregion

        #region Idea Basket
        /// <summary>
        /// Add a Keyword to the user's IdeaBasket.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="keyword">The Keyword to add.</param>
        /// <returns>True if the Keyword was deleted successfully.</returns>
        public bool AddKeywordToIdeaBasket(Guid userId, string keyword)
        {
            throw new NotImplementedException();
        }//end:AddKeywordToIdeaBasket

        /// <summary>
        /// Delete a Keyword from the user's IdeaBasket.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="keyword">The Keyword to delete.</param>
        /// <returns>True if the Keyword was deleted successfully.</returns>
        public bool DeleteIdeaBasketKeyword(Guid userId, string keyword)
        {
            throw new NotImplementedException();
            /*---
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result =
                            IdeBasketOperations.IdeBasketManipulator.DeleteKeywordFromUsersIdeaBasket(
                            userDbId.Value, keyword, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
             * --*/
        }//end:DeleteIdeaBasketKeyword
        #endregion

        #region Bookmark
        /// <summary>
        /// Query the DB for all Bookmarks registered for the given userId.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string QueryBookmarks(Guid userId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = BookmarkOperations.BookmarkManipulator.
                            QueryBookmarksForUser(userDbId.Value, connection);
                    }
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:QueryBookmarks

        /// <summary>
        /// Add a Bookmark to the user's register.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId">Id of the Segment to Bookmark.</param>
        /// <returns>True if the Bookmark was deleted successfully.</returns>
        public bool AddBookmark(Guid userId, int segmentId)
        {
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = BookmarkOperations.BookmarkManipulator.AddSegmentBookmark(
                            userDbId.Value, segmentId, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
        }//end:AddBookmark

        /// <summary>
        /// Delete a Bookmark from the user's register.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId">Id of the Segment for which to delete the Bookmark.</param>
        /// <returns>True if the Bookmark was deleted successfully.</returns>
        public bool DeleteBookmark(Guid userId, int segmentId)
        {
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = BookmarkOperations.BookmarkManipulator.DeleteSegmentBookmark(
                            userDbId.Value, segmentId, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
        }//end:DeleteBookmark
        #endregion

        #region Relations
        /// <summary>
        /// Query the DB for all Relations registered for the given segmentId.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId">Id of the Segment for which to get all relations.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string GetRelations(Guid userId, int segmentId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    //Open DB connection
                    connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                    Result = RelationsOperations.RelationsManipulator.GetRelationsBySegmentId(
                        segmentId, connection);
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:GetRelations

        /// <summary>
        /// Query the DB for all Segments related to a given Segment Id.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="segmentId">Id of the Segment for which to get all other related Segments.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string RelatedSegments(Guid userId, int segmentId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    //Open DB connection
                    connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                    Result = RelationsOperations.RelationsManipulator.GetAllRelatedSegments(
                        segmentId, connection);
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:RelatedSegments
        #endregion

        #region Maps
        /// <summary>
        /// Save the user's Map to the DB.
        /// </summary>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <param name="map">A string (XML) representation of the user's Map.</param>
        /// <returns>True if the Map was saved successfully.</returns>
        public bool SaveMap(Guid userId, string map)
        {
            bool Result = false;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = MapOperations.MapManipulator.SaveUsersMap(
                            userDbId.Value, map, connection);
                    }
                }
                else
                    Result = false;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = false;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of 'False'.
            return Result;
        }//end:SaveMap

        /// <summary>
        /// Get the users's Map from the DB.
        /// </summary>
        /// <remarks>Caller Expects an XmlDocument, 
        /// but since XmlDocument is not serializable, we send the Xml as a string.</remarks>
        /// <param name="userId">The user ID that the user aquired when logging in to the service.</param>
        /// <returns>A string representation of an XmlDocument.</returns>
        public string LoadMap(Guid userId)
        {
            string Result = string.Empty;
            SqlConnection connection = null;

            try
            {
                if (UserManager.VerifyLoggedInUserRecord(userId) == true)
                {
                    int? userDbId = null;
                    UserManager.GetUserDbIdFromUserServiceId(userId, ref userDbId);
                    if (userDbId.HasValue)
                    {
                        //Open DB connection
                        connection = DBConnectionHandler.OpenDBConnection(
                            this.GetDBConnectionString());

                        Result = MapOperations.MapManipulator.GetUsersMap(
                            userDbId.Value, connection);
                    }
                }
                else
                    Result = string.Empty;
            }
            catch (Exception ex)
            {
                ErrorHandler.LogMessage(ex.Message, false);
                Result = string.Empty;
            }
            finally
            {
                if (connection != null)
                    DBConnectionHandler.CloseDBConnection(connection);
            }

            //Always return Result.
            //Let the caller decide the meaning of string.Empty.
            return Result;
        }//end:LoadMap
        #endregion
    }
}
